
#ifndef _SERIAL_included_
#define _SERIAL_included_

#include <Arduino.h>
#include <avr/pgmspace.h>

//
// Workaround for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734
//
#ifdef PROGMEM
#undef PROGMEM
#define PROGMEM __attribute__((section(".progmem.data")))
#endif

/** Store and print a string in flash memory.*/
#define PgmPrint(x) SerialPrint_P(PSTR(x))
/** Store and print a string in flash memory followed by a CR/LF.*/
#define PgmPrintln(x) SerialPrintln_P(PSTR(x))

//#define PRINTF(format, ...) debug_printf(PSTR(format), ## __VA_ARGS__)
//#define PRINTF(format, ...) debug_printf(PSTR(format), ...)
#define PRINTF(format, ...) do { noInterrupts(); printf_P(PSTR(format), ## __VA_ARGS__); interrupts(); } while(0)

//------------------------------------------------------------------------------
/**
 * %Print a string in flash memory to the serial port.
 *
 * \param[in] str Pointer to string stored in flash memory.
 */
static void SerialPrint_P(PGM_P str) {
  for (uint8_t c; (c = pgm_read_byte(str)); str++) {
    //Serial.print(c);
    PRINTF("%c", c);
  }
}

//------------------------------------------------------------------------------
/**
 * %Print a string in flash memory followed by a CR/LF.
 *
 * \param[in] str Pointer to string stored in flash memory.
 */
static inline void SerialPrintln_P(PGM_P str) {
  SerialPrint_P(str);
  //Serial.println();
  PRINTF("\n");
}

#endif // _SERIAL_included_
